﻿#pragma once

#include "Misc/CommonMacros.h"

#include "Containers/String.h"
#include "Containers/Tuple.h"
#include "Path/Path.h"
#include "Platform/SystemEvent.h"

#include "Platform/Window/SystemWindowInterface.h"

#include "Widgets/Mouse/MouseCursorType.h"



class IEventQueueInterface;

enum class EPlatform
{
    Unknown,
    Windows,
    Linux,
    // Android,
    // IOS,
    // Mac,
};

//only support 64 bit machaine, don't use x86,it's too old
enum class EArchitecture
{
    Unknown,
    x64,
    AArch64, //arm64, for android
};


class WHENGINE_API  IPlatformInterface
{
public:
    virtual ~IPlatformInterface() = default;

    static IPlatformInterface* GetPlatformInterface();

    virtual EPlatform GetPlatform() const =0;

    virtual EArchitecture GetArchitecture() const=0;

    //convert a commandline string to unicode
    //on windows, commandline string codec is ANSI,ANSI is changed by system locale
    virtual CString SystemStringToUnicode(const char * InArg) const=0;
    TVector<CString> ConvertArgsToUnicode(int argc, char *argv[]) const;


    virtual TVector<const char*> GetVulkanInstanceExtensions() const=0;

    //create a process and block until it exit
    //return exit code
    virtual int64_t CreateProcess(const CString& Command, const CString& WorkingDirectory)=0;

    //create a process and immediately return
    //return process id
    virtual int64_t CreateProcessWithoutBlock(const CString& Command, const CString& WorkingDirectory)=0;

    virtual void KillProcess(int64_t ProcessID)=0;

    virtual TOptional<SystemEvent> PopEvents() =0;

    virtual ISytemWindowInterface * CreateSystemWindow() =0;

    virtual void DestroySystemWindow(ISytemWindowInterface * Window) =0;

    //get display work area
    //the display is  which one contains the position
    virtual SRect GetDisplayWorkArea(const SIntPoint & InPosition ) const =0;

    //@IMEWidgetPosition, input method widget position, relative to window
    virtual void StartTextInput(uint64_t WindowID, SIntPoint IMEWidgetPosition) =0;

    virtual void StopTextInput()=0;

    virtual bool IsTextInputStarted() const =0;


    virtual void UseSystemCursor(EMouseCursorType CursorType)=0;

    virtual TVector<TTuple<CString /*Displayname*/,SPath>> GetDefaultFavoriteList()=0;

    virtual bool IsKeyDown(EKey Key)=0;


    virtual void SetClipboardText(const CString& Text)=0;
    virtual bool HasClipboardText()=0;
    //return empty string if clipboard is empty
    virtual CString GetClipboardText()=0;

    //捕获鼠标，即便鼠标移出窗口，也能接收到鼠标移动事件
    //在windows上，仅当鼠标按键按下时，才能收到鼠标移动事件
    virtual void CaptureMouse(uint64_t WindowID)=0;
    virtual void ReleaseMouseCapture()=0;

};

namespace WH
{
    WHENGINE_API CString GetPlatformName(EPlatform Platform);
    WHENGINE_API CString GetArchitectureName(EArchitecture Architecture);
}